查看原文
其他

开发者预览版 — 基于 Mobile GPU 的 TensorFlow Lite 处理性能大幅提升

Google TensorFlow 2019-02-15

文 / Google TensorFlow 团队


由于设备的处理和能力有限,在移动设备上基于以计算密集型为主的机器学习模型运行推理,对资源的要求很高。虽然转换为定点模型是加速的一种途径,但用户已经要求我们提供 GPU 支持,并作为加速原始浮点模型推理的一种选项,且不要产生额外的复杂性和潜在的量化精度损失。


我们很高兴地宣布,随着 TensorFlow Lite GPU 后端开发者预览版的发布,对于选定的模型可以利用移动 GPU ( 如下所示 ),对于不支持的部分,将自动使用 CPU 进行推理。在未来的几个月里,我们将继续增加更多的算子,并改善 GPU 整体的后端产品。


新的后端利用 :

  • Android 设备上的 OpenGL ES 3.1 计算着色器( Compute Shaders)

  • iOS 设备上的 Metal 计算着色器


我们新发布的 GPU 后端的预编译二进制预览版,让开发人员和机器学习研究人员可以尽早尝试这种令人兴奋的新技术。我们计划在 2019 年晚些时候发布一个完整的开源版本,其中包括我们收集的开发者反馈。



目前 TensorFlow Lite 仍使用  CPU 浮点推断进行人脸轮廓检测 ( 非人脸识别 )。未来我们会利用新的 GPU 后端,可将 Pixel 3 和三星 S9 的推理速度提升 4 - 6 倍。



GPU 与 CPU 性能

我们已经在 Google 的产品中针对新的 GPU 后端进行了几个月的测试,加速了计算密集型网络,并为我们的用户提供了很多重要的用例。

 

对于 Pixel 3 的肖像模式,TensorFlow Lite GPU 让前景 - 背景分割模型的速度提高了 4 倍 以上,新的深度预估模型的推理速度提高了 10 倍 以上。在 YouTube 上的 YouTube Stories 和 Playground Stickers 中,我们的实时视频分割模型在各种手机上的速度提高了 5 - 10 倍

 

我们发现,对于各种各样的深度神经网络模型,新的 GPU 后端通常比浮点 CPU 实现速度快 2 - 7 倍。下面,我们对 4 个公共和 2 个内部模型进行了基准测试,涵盖了开发人员和研究人员在一组 Android 和 Apple 设备上遇到的常见用例:

 

公共模型:

  1. MobileNet v1(224 x 224)图像分类

    ( 专为移动和嵌入式视觉应用而设计的图像分类模型 )

    下载地址:https://ai.googleblog.com/2017/06/mobilenets-open-source-models-for.html


  2. 用于姿势估计的 PoseNet 

    ( 估计图像或视频中人物姿势的视觉模型 )

    下载地址:https://github.com/tensorflow/tfjs-models/tree/master/posenet


  3. DeepLab 分割(257 x 257)

    ( 图像分割模型,为输入图像中的每个像素分配语义标签,例如,狗,猫,汽车 )

    下载地址:https://ai.googleblog.com/2018/03/semantic-image-segmentation-with.html


  4. MobileNet SSD 对象检测

    ( 检测带有边框的多个对象的图像分类模型 )

    下载地址:https://ai.googleblog.com/2018/07/accelerated-training-and-inference-with.html


Google 专有用例:

  1. MLKit

  2. Playground Stickers 和 YouTube Stories 使用的实时视频分段



GPU 加速对于更复杂的神经网络模型来说是最重要的,这些模型可以更好地利用 GPU,例如密集预测 / 分段或分类任务。在非常小的模型中,加速效果可能略差,而使用 CPU 可以有利于避免内存传输中固有的延迟成本。



如何使用?

教程

最简单的入门方法是按照 教程 使用带有 GPU 委托的 TensorFlow Lite 演示应用程序(https://www.tensorflow.org/lite/performance/gpu)


以下是对使用情况的简要概述,有关更多信息,请参阅我们的 完整文档(https://www.tensorflow.org/lite/performance/gpu_advanced%E3%80%82)


使用 Java for Android

我们已经准备了一个完整的 Android 存档 ( AAR ),包括带有 GPU 后端的 TensorFlow Lite。编辑 gradle 文件替换当前版本,以包含这个 AAR,并将此代码片段添加到 Java 初始化代码中。

// Initialize interpreter with GPU delegate.

GpuDelegate delegate = new GpuDelegate();

Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);

Interpreter interpreter = new Interpreter(model, options);

 

// Run inference.

while (true) {

  writeToInputTensor(inputTensor);

  interpreter.run(inputTensor, outputTensor);

  readFromOutputTensor(outputTensor);

}

 

// Clean up.

delegate.close();


使用 C ++ for iOS

  • 步骤 1,下载 TensorFlow Lite 的二进制版本

  • 步骤 2,更改代码,在创建模型之后调用 ModifyGraphWithDelegate()

// Initialize interpreter with GPU delegate.

std::unique_ptr<Interpreter> interpreter;

InterpreterBuilder(model, op_resolver)(&interpreter);

auto* delegate = NewGpuDelegate(nullptr);  // default config

if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;

 

// Run inference.

while (true) {

  WriteToInputTensor(interpreter->typed_input_tensor<float>(0));

  if (interpreter->Invoke() != kTfLiteOk) return false;

  ReadFromOutputTensor(interpreter->typed_output_tensor<float>(0));

}

 

// Clean up.

interpreter = nullptr;

DeleteGpuDelegate(delegate);



如何加速?

GPU 后端目前支持选择操作 ( 请参阅 文档 https://www.tensorflow.org/lite/performance/gpu_advanced  )。仅包含这些操作时,您的模型将运行得最快;不支持的 GPU 操作将自动退回到 CPU。



它是如何工作的?

深度神经网络按顺序运行数百个操作,使它们非常适合 GPU,这些 GPU 的设计考虑了面向吞吐量的并行工作负载。


Interpreter::ModifyGraphWithDelegate() 在 Objective-C ++ 中调用时初始化 GPU,或者通过 Interpreter.Options  间接调用 Interpreter 的构造函数来初始化 GPU。在初始化阶段,基于从框架接收的执行计划构建输入神经网络的规范表示。使用这种新的表示,可应用一组转换规则,包括但不限于:

  • 剔除不需要的算子

  • 将算子替换为性能更好的等效算子

  • 合并算子,以减少最终生成的着色程序的数量

 

基于此优化图(optimized graph),生成并编译计算着色器。我们目前在 Android 上使用 OpenGL ES 3.1 计算着色器,在 iOS 上使用 Metal 计算着色器。在创建这些计算着色器时,我们还采用了各种特定于体系结构的优化,例如:

  • 应用某些操作的特化而不是它们的通用实现

  • 释放寄存器压力

  • 选择最佳工作组大小

  • 安全地调整精度

  • 重新排序显式数学操作

 

在这些优化结束时,着色器程序被编译,可能需要几毫秒到半秒,就像手机游戏一样。一旦着色程序编译完成,新的 GPU 推理引擎就可以开始工作了。


在推断每个输入时:

  • 如有必要,输入将移至 GPU:输入张量(如果尚未存储为 GPU 内存)可由框架通过创建 GL 缓冲区或 MTLBuffers 进行 GPU 访问,同时还可能复制数据。由于 GPU 在 4 通道数据结构中效率最高,因此通道大小不等于 4 的张量将重新调整为更加适合 GPU 的布局

  • 执行着色器程序:将上述着色器程序插入命令缓冲区队列中,GPU 将这些程序输出。在此步骤中,我们还为中间张量管理 GPU 内存,以尽可能减少后端的内存占用

  • 必要时将输出移动到 CPU:一旦深度神经网络完成处理,框架将结果从 GPU 内存复制到 CPU 内存,除非网络的输出可以直接在屏幕上呈现,不需要这样的传输

 

为了获得最佳体验,我们建议优化输入 / 输出张量复制和 / 或网络架构。有关此类优化的详细信息,可以在 TensorFlow Lite GPU 文档中找到。


有关性能最佳实践,请阅读 指南(

https://www.tensorflow.org/lite/performance/best_practices)


它有多大?

GPU 委托将给 Android armeabi-v7a APK 增加 270KB,给 iOS 增加 212KB。但后端是可选的,因此,如果不使用 GPU 委托,就不需要包含它。



未来的工作

这只是我们 GPU 支持工作的开始。除了社区反馈外,我们还打算进行以下改进:

  • 增加算子的范围

  • 进一步优化性能

  • 完善并最终发布 API


希望您可以将想法和评论发表在我们的 GitHub 和 StackOverflow 页面上。



感谢

Andrei Kulik, Juhyun Lee, Nikolay Chirkov, Ekaterina Ignasheva, Raman Sarokin, Yury Pisarchyk, Matthias Grundmann, Andrew Selle, Yu-Cheng Ling, Jared Duke, Lawrence Chan, Tim Davis, Pete Warden, Sarah Sirajuddin



更多 AI 相关阅读:



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存